#include "main.h"
#include "ParseSDT.h"
#include "ParseTS_Head.h"
#include "ParseType.h"

void ParseSDT_Section(unsigned char SDTtable[1200],TS_SDT *NewSdtPoint);
static int sdt_i,sdt_n,sdt_l;
static unsigned int SDT_CRC[4096];
static unsigned char SDT_Long_Table[1200];
static unsigned char CountSdt;

void TSSDT_Table(unsigned char SDTtable[1200],TS_SDT *NewSdtPoint)
{
	int SDT_Length = 0;

	NewSdtPoint->table_id = SDTtable[0];
	NewSdtPoint->section_syntax_indicator = SDTtable[1] >> 7;
	NewSdtPoint->reserved_future_use_1 = (SDTtable[1] >> 6) & 0x01;
	NewSdtPoint->reserved_1 = (SDTtable[1] >> 4) & 0x03;
	NewSdtPoint->section_length = ((SDTtable[1] & 0x0F) << 8) | SDTtable[2];
	NewSdtPoint->transport_stream_id = (SDTtable[3] << 8) | SDTtable[4];
	NewSdtPoint->reserved_2 = SDTtable[5] >> 6;
	NewSdtPoint->version_number = (SDTtable[5] >> 1) & 0x1F;
	NewSdtPoint->current_next_indicator = (SDTtable[5] << 7) >> 7;
	NewSdtPoint->section_number = SDTtable[6];
	NewSdtPoint->last_section_number = SDTtable[7];
	NewSdtPoint->original_network_id = (SDTtable[8] << 8) | SDTtable[9];
	NewSdtPoint->reserved_future_use_2 = SDTtable[10];

	ParseSDT_Section(SDTtable, NewSdtPoint);

	SDT_Length = NewSdtPoint->section_length + 3;
	NewSdtPoint->CRC_32 = (SDTtable[SDT_Length - 4] << 24) | (SDTtable[SDT_Length - 3] << 16)
	        | (SDTtable[SDT_Length - 2] << 8) | SDTtable[SDT_Length - 1];

	if(NewSdtPoint->section_length > 188)
	{
		sdt_l = NewSdtPoint->section_length;
	}

	if((NewSdtPoint->section_length < 188 && NewSdtPoint->CRC_32 != 0) || ((sdt_l / 188) == sdt_n && NewSdtPoint->CRC_32 != 0))
	{
		if(sdt_i == 0)
		{
			NewSdtPoint->next = NULL;
			NewSdtPoint->Previous = SdtPoint;
			SdtPoint->next = NewSdtPoint;
			SdtPoint = SdtPoint->next;

			SDT_CRC[sdt_i] = NewSdtPoint->CRC_32;

			sdt_i ++;
		}else
		{
			for(int p = 0; p < sdt_i; p++)
			{
				if(SDT_CRC[p] == NewSdtPoint->CRC_32)
				{
					return;
				}
			}
				NewSdtPoint->next = NULL;
				NewSdtPoint->Previous = SdtPoint;
				SdtPoint->next = NewSdtPoint;
				SdtPoint = SdtPoint->next;

				SDT_CRC[sdt_i] = NewSdtPoint->CRC_32;

				sdt_i ++;
		}
	}

}

void ParseSDT_Section(unsigned char SDTtable[1200],TS_SDT *NewSdtPoint)
{
	int SDT_Length = 0;
	int ServiceCount = 0;
	int ServicePosition = 11;
	unsigned char descriptor[204];

    SDT_Length = NewSdtPoint->section_length + 3;

	for (ServicePosition; ServicePosition < SDT_Length - 4; ServicePosition += 5)
	{
		NewSdtPoint->SDT_Service[ServiceCount].service_id = (SDTtable[ServicePosition] << 8)
		        | SDTtable[ServicePosition + 1];
		NewSdtPoint->SDT_Service[ServiceCount].reserved_future_use = SDTtable[ServicePosition + 2] >> 2;
		NewSdtPoint->SDT_Service[ServiceCount].EIT_schedule_flag = (SDTtable[ServicePosition + 2] & 0x03) >> 1;
		NewSdtPoint->SDT_Service[ServiceCount].EIT_present_following_flag = SDTtable[ServicePosition + 2] & 0x01;
		NewSdtPoint->SDT_Service[ServiceCount].running_status = SDTtable[ServicePosition + 3] >> 5;
		NewSdtPoint->SDT_Service[ServiceCount].free_CA_mode = (SDTtable[ServicePosition + 3] & 0x1F) >> 4;
		NewSdtPoint->SDT_Service[ServiceCount].descriptors_loop_length = ((SDTtable[ServicePosition + 3] & 0x0F) << 8)
		        | SDTtable[ServicePosition + 4];

		if (NewSdtPoint->SDT_Service[ServiceCount].descriptors_loop_length != 0)
		{
			memcpy(NewSdtPoint->SDT_Service[ServiceCount].descriptor, SDTtable + 5 + ServicePosition,
			        NewSdtPoint->SDT_Service[ServiceCount].descriptors_loop_length);
			ServicePosition += NewSdtPoint->SDT_Service[ServiceCount].descriptors_loop_length; 
		}

		ServiceCount++;
		
	}
}



void ParseTS_SDT_1(int TsPackage_len,TS_Package_Head TS_PackageSDTHead)
{
    TS_SDT TS_PackageSDT = {0};
	unsigned char SDTtable[204] = {0};
	TS_SDT *NewSdtPoint = (TS_SDT *)malloc(sizeof(TS_SDT));
	
	CountSdt = TS_PackageSDTHead.continuity_counter;

    memcpy(SDTtable, TSdata+5, TsPackage_len-5);

    TSSDT_Table(SDTtable, NewSdtPoint);

	sdt_n = 0;	
	memset(SDT_Long_Table, 0, 1200);
	memcpy(SDT_Long_Table, TSdata+5, TsPackage_len-5);
}

void ParseTS_SDT_0(int TsPackage_len,TS_Package_Head TS_PackageSDTHead)
{
    TS_SDT TS_PackageSDT = {0};
	unsigned char SDTtable[204] = {0};

    memcpy(SDTtable, TSdata+4, TsPackage_len-4);

	if(sdt_n == 0 && CountSdt+1 == TS_PackageSDTHead.continuity_counter)
	{
		memcpy(SDT_Long_Table+183, SDTtable, TsPackage_len-4);
		CountSdt++;
		sdt_n++;
	}else if(CountSdt+1 == TS_PackageSDTHead.continuity_counter)
	{
		memcpy(SDT_Long_Table+(183+(184*sdt_n)), SDTtable, TsPackage_len-4);
		CountSdt++;
		sdt_n++;
	}

	if((sdt_l / 188) == sdt_n)
	{
		TS_SDT *NewSDTPoint = (TS_SDT *)malloc(sizeof(TS_SDT));
		TSSDT_Table(SDT_Long_Table, NewSDTPoint);
		sdt_n = 0;
		memset(SDT_Long_Table, 0, 1200);
	}
}